package pers.vic.upload.business.service;


import cn.xuqiudong.common.base.model.BaseResponse;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.validator.GenericValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import pers.vic.upload.business.model.AssertModel;
import pers.vic.upload.constant.FileType;
import pers.vic.upload.constant.ResultEnum;

import java.io.File;
import java.text.ParseException;
import java.util.*;

/**
 * 描述: 业务处理父类
 * @author Vic.xu
 * @date 2022-07-19 10:49
 */
public abstract class BaseBusinessService<T> {

    public static final String DATE_FORMAT = "yyyyMMdd";

    /**初始状态*/
    protected static final String STATUS = "PENDING";

    @Autowired
    protected JdbcTemplate jdbcTemplate;

    @Autowired
    protected AttachmentService attachmentService;

    /**
     * 类型
     * @return FileType
     */
    public abstract FileType type();

    /**
     * 文件名校验
     * @param fileName 文件名
     * @param ignoreUnique  是否忽略唯一性校验
     * @return is valid
     */
    public abstract BaseResponse<T> check(String fileName, boolean ignoreUnique);

    /**
     * 文件名对应的数据是否在表中唯一
     * @param map 文件名各部分，如果是参数项 则已转换后的
     * @return boolean
     */
    protected abstract boolean existFileNameDataCheck(Map<Integer, String> map);

    /**
     * 保存对象 以及关联附件
     * @param file file
     * @return
     */
    public BaseResponse<?> saveAndRelation(File file) {
        String fileName = file.getName();
        BaseResponse<T> check = check(fileName, true);
        if (!check.isSuccess()) {
            return check;
        }
        String id = save(check.getData());
        String attachmentId = attachmentService.insert(file);
        saveRelation(id, attachmentId);
        return BaseResponse.success();

    }

    /**
     * 保存入库
     * @param model model
     * @return id
     */
    public abstract String save(T model);

    /**
     * 保存附件
     * @param id 主表id
     * @param attachmentId 附件id
     */
    public abstract void saveRelation(String id, String attachmentId);


    /**
     * 识别号是否存在
     * @param identityCode 识别号
     * @return true or false
     */
    public abstract boolean identityCodeCheck(String identityCode);

    /* ****************************************************** */


    /**
     * 根据识别号查询资产id
     * 只找状态为"在建"、"在租"、"待租"的海事资产，排除"出售"状态的。”，
     * 根据台账提供的状态描述：1:在建，2：在购，3：待租，4：在租，5：闲置，6：报废，7：出售。改为查找1，3，4
     * @param identifyCode 识别号
     * @return 资产id
     */
    public AssertModel findAsset(String identifyCode) {
        String sql = "select id, a.identify_method as method, a.ship_flag as shipFlag, a.reg_port as regPort   from t_mpl_wartercraft a " +
                " where a.identify_code = ? and  a.status in ('1', '3', '4') and rownum < 2";
        try {
            AssertModel assertModel = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<AssertModel>(AssertModel.class), identifyCode);

            String ownerShipSql = "select a.name from t_stl_s_subsidiary a where id in " +
                    " (select * from ( " +
                    " select c.fk_lessor_subsidiary_id " +
                    " from t_mpl_wartercraft a" +
                    " left join t_stl_s_asset b on a.id = b.fk_wartercraft_id " +
                    " left join t_stl_s_contract c on c.id = b.fk_contract_id" +
                    " where a.id = ?   " +
                    " order by c.create_date desc" +
                    " ) where rownum <=1" +
                    " )";
            List<String> ownerShips = jdbcTemplate.queryForList(ownerShipSql, String.class, assertModel.getId());
            if (CollectionUtils.isNotEmpty(ownerShips)) {
                assertModel.setOwnership(ownerShips.get(0));
            }
            return assertModel;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    /**
     * 查询数据项
     * 识别方法：identifyMethodMp;
     * 证书类型：meCertificateType;
     * 保险类型：mpInsureType;
     * 是否为我司或我司spv：isOrNot
     * 币种： currency
     * @param pcode pcode
     * @param name name or enName 不区分大小写
     * @return value
     */
    public BaseResponse<String> queryOptionValue(String pcode, String name) {
        if (name != null) {
            name = name.toLowerCase();
        }
        String sql = "SELECT a.VALUE FROM t_stl_s_option a LEFT JOIN t_stl_s_parameter b " +
                " ON a.FK_PARAMETER_ID = b.ID" +
                " WHERE a.enable_flag = 1 and  b.CODE = ? and ( lower(a.NAME) = ? or lower(a.en_name) = ?)  and rownum < 2";
        String value = null;
        try {
            value = jdbcTemplate.queryForObject(sql, String.class, pcode, name, name);
        } catch (Exception ex) {
            // EmptyResultDataAccessException
        }

        if (StringUtils.isBlank(value)) {
            return BaseResponse.error(ResultEnum.NON_EXIST_PARAMETER_ITEM.getCode(), ResultEnum.NON_EXIST_PARAMETER_ITEM.getMsg() + ": " + name);
        }
        return BaseResponse.success(value);
    }


     /*
      ICBCSTL-68545
      命名规则： 修改了
      识别号_保险类型（对应英文）_起始日期-截止日期；   保险
      识别号_证书类型（对应英文）_起始日期-截止日期；   权证
      具体类型对应英文参照01；命名规则参照02
     */

    /**
     * 把filename转换为map：xx_yy_zz.pdf --> 1:xx,2:yy,3:zz
     * @param fileName file name
     * @return map
     */
    public static Map<Integer, String> splitFileName(String fileName) {
        if (StringUtils.isBlank(fileName)) {
            return null;
        }
        Map<Integer, String> fileMap = new HashMap<>();
        fileName = StringUtils.substringBeforeLast(fileName, ".");
        String[] ss = fileName.split("_");
        int index = 1;
        for (int i = 0; i < ss.length; i++) {
            //第三位是 起始日期-截止日期 需要分成两份
            if (i == 2) {
                String date = ss[i];
                if (fileName.split("-").length == 2) {
                    fileMap.put(index++, date.split("-")[0]);
                    fileMap.put(index++, date.split("-")[1]);
                }
            } else {
                fileMap.put(index++, ss[i]);
            }
        }
        return fileMap;
    }

    /**
     * is not date
     * @param dateStr string date
     * @return true or false
     */
    public static boolean isNotDate(String dateStr) {
        return !GenericValidator.isDate(dateStr, DATE_FORMAT, true);
    }

    /**
     * to date
     * @param dateStr dateStr
     * @return date
     */
    public static Date toDate(String dateStr) {
        try {
            return DateUtils.parseDate(dateStr, DATE_FORMAT);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**测试查询*/
    public abstract List<Map<String, Object>> find();


}
